/*!
 * \file WtRdmDtReader.h
 * \project	WonderTrader
 *
 * \author Wesley
 * \date 2020/03/30
 * 
 * \brief WonderTrader随机数据读取器头文件
 * 
 * \details 该文件定义了WtRdmDtReader随机数据读取器类，提供了用于随机访问历史数据的读取功能。
 *          主要特点包括：
 *          - 继承自IRdmDtReader接口，提供标准化的随机数据读取接口
 *          - 支持多种数据类型：K线、Tick、委托队列、委托明细、成交明细
 *          - 提供实时数据块和历史数据块的管理
 *          - 支持数据缓存机制，提高读取性能
 *          - 支持复权因子的加载和处理
 *          - 提供按时间范围和按数量的数据切片功能
 *          - 基于内存映射文件的高效数据访问
 */
#pragma once
#include <string>
#include <stdint.h>

#include "DataDefine.h"

#include "../Includes/FasterDefs.h"
#include "../Includes/IRdmDtReader.h"

#include "../Share/BoostMappingFile.hpp"
#include "../Share/StdUtils.hpp"

NS_WTP_BEGIN
class WTSVariant;
class WTSTickSlice;
class WTSKlineSlice;
class WTSOrdDtlSlice;
class WTSOrdQueSlice;
class WTSTransSlice;
class WTSArray;

class IBaseDataMgr;
class IHotMgr;
typedef std::shared_ptr<BoostMappingFile> BoostMFPtr;

/*!
 * \class WtRdmDtReader
 * \brief WonderTrader随机数据读取器
 * 
 * \details 该类实现了IRdmDtReader接口，提供随机访问历史数据的读取功能。
 *          主要功能包括：
 *          - 支持多种数据类型的随机读取：K线、Tick、Level2数据
 *          - 提供实时数据块的内存映射和缓存管理
 *          - 支持历史数据的文件读取和缓存机制
 *          - 提供按时间范围和按数量两种数据切片方式
 *          - 支持复权因子的加载和应用
 *          - 采用线程安全的数据访问机制
 *          - 基于boost内存映射文件的高性能数据访问
 * 
 * \note 该类主要用于策略回测和数据分析场景
 * \note 支持的数据格式为WonderTrader标准格式
 * 
 * \see IRdmDtReader
 */
class WtRdmDtReader : public IRdmDtReader
{
public:
	/*!
	 * \brief 构造函数
	 * 
	 * 初始化随机数据读取器实例
	 */
	WtRdmDtReader();
	
	/*!
	 * \brief 析构函数
	 * 
	 * 清理资源并释放内存
	 */
	virtual ~WtRdmDtReader();

private:
	/*!
	 * \struct RTKlineBlockPair
	 * \brief 实时K线数据块对
	 * 
	 * \details 用于管理实时K线数据的内存映射文件和数据块
	 *          包含线程安全机制和容量跟踪功能
	 */
	typedef struct _RTKBlockPair
	{
		StdUniqueMutex*	_mtx;		///< 线程安全互斥锁
		RTKlineBlock*	_block;		///< 实时K线数据块指针
		BoostMFPtr		_file;		///< 内存映射文件指针
		uint64_t		_last_cap;	///< 最后容量大小
		uint64_t		_last_time;	///< 最后更新时间

		/*!
		 * \brief 构造函数
		 * 
		 * 初始化所有成员变量为默认值
		 */
		_RTKBlockPair()
		{
			_mtx = new StdUniqueMutex();
			_block = NULL;
			_file = NULL;
			_last_cap = 0;
			_last_time = 0;
		}
		
		/*!
		 * \brief 析构函数
		 * 
		 * 释放互斥锁资源
		 */
		~_RTKBlockPair() { delete _mtx; }

	} RTKlineBlockPair;
	typedef faster_hashmap<std::string, RTKlineBlockPair>	RTKBlockFilesMap;

	/*!
	 * \struct TickBlockPair
	 * \brief Tick数据块对
	 * 
	 * \details 用于管理实时Tick数据的内存映射文件和数据块
	 *          包含线程安全机制和容量跟踪功能
	 */
	typedef struct _TBlockPair
	{
		StdUniqueMutex*	_mtx;		///< 线程安全互斥锁
		RTTickBlock*	_block;		///< 实时Tick数据块指针
		BoostMFPtr		_file;		///< 内存映射文件指针
		uint64_t		_last_cap;	///< 最后容量大小
		uint64_t		_last_time;	///< 最后更新时间

		/*!
		 * \brief 构造函数
		 * 
		 * 初始化所有成员变量为默认值
		 */
		_TBlockPair()
		{
			_block = NULL;
			_file = NULL;
			_last_cap = 0;
			_last_time = 0;
			_mtx = new StdUniqueMutex();
		}
		
		/*!
		 * \brief 析构函数
		 * 
		 * 释放互斥锁资源
		 */
		~_TBlockPair() { delete _mtx; }
	} TickBlockPair;
	typedef faster_hashmap<std::string, TickBlockPair>	TBlockFilesMap;

	/*!
	 * \struct TransBlockPair
	 * \brief 成交明细数据块对
	 * 
	 * \details 用于管理实时成交明细数据的内存映射文件和数据块
	 *          包含线程安全机制和容量跟踪功能
	 */
	typedef struct _TransBlockPair
	{
		StdUniqueMutex*	_mtx;		///< 线程安全互斥锁
		RTTransBlock*	_block;		///< 实时成交明细数据块指针
		BoostMFPtr		_file;		///< 内存映射文件指针
		uint64_t		_last_cap;	///< 最后容量大小
		uint64_t		_last_time;	///< 最后更新时间

		/*!
		 * \brief 构造函数
		 * 
		 * 初始化所有成员变量为默认值
		 */
		_TransBlockPair()
		{
			_mtx = new StdUniqueMutex();
			_block = NULL;
			_file = NULL;
			_last_cap = 0;
			_last_time = 0;
		}
		
		/*!
		 * \brief 析构函数
		 * 
		 * 释放互斥锁资源
		 */
		~_TransBlockPair() { delete _mtx; }
	} TransBlockPair;
	typedef faster_hashmap<std::string, TransBlockPair>	TransBlockFilesMap;

	/*!
	 * \struct OrdDtlBlockPair
	 * \brief 委托明细数据块对
	 * 
	 * \details 用于管理实时委托明细数据的内存映射文件和数据块
	 *          包含线程安全机制和容量跟踪功能
	 */
	typedef struct _OdeDtlBlockPair
	{
		StdUniqueMutex*	_mtx;		///< 线程安全互斥锁
		RTOrdDtlBlock*	_block;		///< 实时委托明细数据块指针
		BoostMFPtr		_file;		///< 内存映射文件指针
		uint64_t		_last_cap;	///< 最后容量大小
		uint64_t		_last_time;	///< 最后更新时间

		/*!
		 * \brief 构造函数
		 * 
		 * 初始化所有成员变量为默认值
		 */
		_OdeDtlBlockPair()
		{
			_mtx = new StdUniqueMutex();
			_block = NULL;
			_file = NULL;
			_last_cap = 0;
			_last_time = 0;
		}
		
		/*!
		 * \brief 析构函数
		 * 
		 * 释放互斥锁资源
		 */
		~_OdeDtlBlockPair() { delete _mtx; }
	} OrdDtlBlockPair;
	typedef faster_hashmap<std::string, OrdDtlBlockPair>	OrdDtlBlockFilesMap;

	/*!
	 * \struct OrdQueBlockPair
	 * \brief 委托队列数据块对
	 * 
	 * \details 用于管理实时委托队列数据的内存映射文件和数据块
	 *          包含线程安全机制和容量跟踪功能
	 */
	typedef struct _OdeQueBlockPair
	{
		StdUniqueMutex*	_mtx;		///< 线程安全互斥锁
		RTOrdQueBlock*	_block;		///< 实时委托队列数据块指针
		BoostMFPtr		_file;		///< 内存映射文件指针
		uint64_t		_last_cap;	///< 最后容量大小
		uint64_t		_last_time;	///< 最后更新时间

		/*!
		 * \brief 构造函数
		 * 
		 * 初始化所有成员变量为默认值
		 */
		_OdeQueBlockPair()
		{
			_mtx = new StdUniqueMutex();
			_block = NULL;
			_file = NULL;
			_last_cap = 0;
			_last_time = 0;
		}
		
		/*!
		 * \brief 析构函数
		 * 
		 * 释放互斥锁资源
		 */
		~_OdeQueBlockPair() { delete _mtx; }
	} OrdQueBlockPair;
	typedef faster_hashmap<std::string, OrdQueBlockPair>	OrdQueBlockFilesMap;

	RTKBlockFilesMap	_rt_min1_map;	///< 1分钟K线数据块映射表
	RTKBlockFilesMap	_rt_min5_map;	///< 5分钟K线数据块映射表

	TBlockFilesMap		_rt_tick_map;	///< Tick数据块映射表
	TransBlockFilesMap	_rt_trans_map;	///< 成交明细数据块映射表
	OrdDtlBlockFilesMap	_rt_orddtl_map;	///< 委托明细数据块映射表
	OrdQueBlockFilesMap	_rt_ordque_map;	///< 委托队列数据块映射表

	/*!
	 * \struct HisTBlockPair
	 * \brief 历史Tick数据块对
	 * 
	 * \details 用于管理历史Tick数据的读取和缓存
	 *          包含日期标识和数据缓冲区
	 */
	typedef struct _HisTBlockPair
	{
		HisTickBlock*	_block;		///< 历史Tick数据块指针
		uint64_t		_date;		///< 数据日期
		std::string		_buffer;	///< 数据缓冲区

		/*!
		 * \brief 构造函数
		 * 
		 * 初始化所有成员变量为默认值
		 */
		_HisTBlockPair()
		{
			_block = NULL;
			_date = 0;
			_buffer.clear();
		}
	} HisTBlockPair;

	typedef faster_hashmap<std::string, HisTBlockPair>	HisTickBlockMap;

	/*!
	 * \struct HisTransBlockPair
	 * \brief 历史成交明细数据块对
	 * 
	 * \details 用于管理历史成交明细数据的读取和缓存
	 *          包含日期标识和数据缓冲区
	 */
	typedef struct _HisTransBlockPair
	{
		HisTransBlock*	_block;		///< 历史成交明细数据块指针
		uint64_t		_date;		///< 数据日期
		std::string		_buffer;	///< 数据缓冲区

		/*!
		 * \brief 构造函数
		 * 
		 * 初始化所有成员变量为默认值
		 */
		_HisTransBlockPair()
		{
			_block = NULL;
			_date = 0;
			_buffer.clear();
		}
	} HisTransBlockPair;

	typedef faster_hashmap<std::string, HisTransBlockPair>	HisTransBlockMap;

	/*!
	 * \struct HisOrdDtlBlockPair
	 * \brief 历史委托明细数据块对
	 * 
	 * \details 用于管理历史委托明细数据的读取和缓存
	 *          包含日期标识和数据缓冲区
	 */
	typedef struct _HisOrdDtlBlockPair
	{
		HisOrdDtlBlock*	_block;		///< 历史委托明细数据块指针
		uint64_t		_date;		///< 数据日期
		std::string		_buffer;	///< 数据缓冲区

		/*!
		 * \brief 构造函数
		 * 
		 * 初始化所有成员变量为默认值
		 */
		_HisOrdDtlBlockPair()
		{
			_block = NULL;
			_date = 0;
			_buffer.clear();
		}
	} HisOrdDtlBlockPair;

	typedef faster_hashmap<std::string, HisOrdDtlBlockPair>	HisOrdDtlBlockMap;

	/*!
	 * \struct HisOrdQueBlockPair
	 * \brief 历史委托队列数据块对
	 * 
	 * \details 用于管理历史委托队列数据的读取和缓存
	 *          包含日期标识和数据缓冲区
	 */
	typedef struct _HisOrdQueBlockPair
	{
		HisOrdQueBlock*	_block;		///< 历史委托队列数据块指针
		uint64_t		_date;		///< 数据日期
		std::string		_buffer;	///< 数据缓冲区

		/*!
		 * \brief 构造函数
		 * 
		 * 初始化所有成员变量为默认值
		 */
		_HisOrdQueBlockPair()
		{
			_block = NULL;
			_date = 0;
			_buffer.clear();
		}
	} HisOrdQueBlockPair;

	typedef faster_hashmap<std::string, HisOrdQueBlockPair>	HisOrdQueBlockMap;

	HisTickBlockMap		_his_tick_map;		///< 历史Tick数据块映射表
	HisOrdDtlBlockMap	_his_orddtl_map;	///< 历史委托明细数据块映射表
	HisOrdQueBlockMap	_his_ordque_map;	///< 历史委托队列数据块映射表
	HisTransBlockMap	_his_trans_map;		///< 历史成交明细数据块映射表

private:
	/*!
	 * \brief 获取实时K线数据块
	 * \param exchg 交易所代码
	 * \param code 合约代码
	 * \param period K线周期
	 * \return 实时K线数据块指针
	 */
	RTKlineBlockPair* getRTKilneBlock(const char* exchg, const char* code, WTSKlinePeriod period);
	
	/*!
	 * \brief 获取实时Tick数据块
	 * \param exchg 交易所代码
	 * \param code 合约代码
	 * \return Tick数据块指针
	 */
	TickBlockPair* getRTTickBlock(const char* exchg, const char* code);
	
	/*!
	 * \brief 获取实时委托队列数据块
	 * \param exchg 交易所代码
	 * \param code 合约代码
	 * \return 委托队列数据块指针
	 */
	OrdQueBlockPair* getRTOrdQueBlock(const char* exchg, const char* code);
	
	/*!
	 * \brief 获取实时委托明细数据块
	 * \param exchg 交易所代码
	 * \param code 合约代码
	 * \return 委托明细数据块指针
	 */
	OrdDtlBlockPair* getRTOrdDtlBlock(const char* exchg, const char* code);
	
	/*!
	 * \brief 获取实时成交明细数据块
	 * \param exchg 交易所代码
	 * \param code 合约代码
	 * \return 成交明细数据块指针
	 */
	TransBlockPair* getRTTransBlock(const char* exchg, const char* code);

	/*!
	 * \brief 从文件缓存历史K线数据
	 * \param key 缓存键值
	 * \param stdCode 标准合约代码
	 * \param period K线周期
	 * \return 是否缓存成功
	 * 
	 * 从磁盘文件读取历史K线数据并缓存到内存中
	 */
	bool		cacheHisBarsFromFile(const std::string& key, const char* stdCode, WTSKlinePeriod period);

	/*!
	 * \brief 按时间范围从缓存中读取K线数据
	 * \param key 缓存键值
	 * \param stime 开始时间
	 * \param etime 结束时间
	 * \param ayBars 输出K线数据数组
	 * \param isDay 是否为日线数据
	 * \return 读取的数据条数
	 */
	uint32_t		readBarsFromCacheByRange(const std::string& key, uint64_t stime, uint64_t etime, std::vector<WTSBarStruct>& ayBars, bool isDay = false);
	
	/*!
	 * \brief 按时间范围从缓存中索引K线数据
	 * \param key 缓存键值
	 * \param stime 开始时间
	 * \param etime 结束时间
	 * \param count 输出数据条数
	 * \param isDay 是否为日线数据
	 * \return K线数据指针
	 */
	WTSBarStruct*	indexBarFromCacheByRange(const std::string& key, uint64_t stime, uint64_t etime, uint32_t& count, bool isDay = false);

	/*!
	 * \brief 按数量从缓存中索引K线数据
	 * \param key 缓存键值
	 * \param etime 结束时间
	 * \param count 输入输出数据条数
	 * \param isDay 是否为日线数据
	 * \return K线数据指针
	 */
	WTSBarStruct*	indexBarFromCacheByCount(const std::string& key, uint64_t etime, uint32_t& count, bool isDay = false);

	/*!
	 * \brief 从文件加载股票复权因子
	 * \param adjfile 复权因子文件路径
	 * \return 是否加载成功
	 */
	bool	loadStkAdjFactorsFromFile(const char* adjfile);
	

//////////////////////////////////////////////////////////////////////////
//IRdmDtReader接口实现
public:
	/*!
	 * \brief 初始化随机数据读取器
	 * \param cfg 配置参数
	 * \param sink 回调接口
	 * 
	 * 根据配置参数初始化数据读取器，设置数据路径和相关管理器
	 */
	virtual void init(WTSVariant* cfg, IRdmDtReaderSink* sink) override;

	/*!
	 * \brief 按时间范围读取委托明细数据切片
	 * \param stdCode 标准合约代码
	 * \param stime 开始时间
	 * \param etime 结束时间，0表示到最新数据
	 * \return 委托明细数据切片
	 */
	virtual WTSOrdDtlSlice*	readOrdDtlSliceByRange(const char* stdCode, uint64_t stime, uint64_t etime = 0) override;
	
	/*!
	 * \brief 按时间范围读取委托队列数据切片
	 * \param stdCode 标准合约代码
	 * \param stime 开始时间
	 * \param etime 结束时间，0表示到最新数据
	 * \return 委托队列数据切片
	 */
	virtual WTSOrdQueSlice*	readOrdQueSliceByRange(const char* stdCode, uint64_t stime, uint64_t etime = 0) override;
	
	/*!
	 * \brief 按时间范围读取成交明细数据切片
	 * \param stdCode 标准合约代码
	 * \param stime 开始时间
	 * \param etime 结束时间，0表示到最新数据
	 * \return 成交明细数据切片
	 */
	virtual WTSTransSlice*	readTransSliceByRange(const char* stdCode, uint64_t stime, uint64_t etime = 0) override;

	/*!
	 * \brief 按时间范围读取Tick数据切片
	 * \param stdCode 标准合约代码
	 * \param stime 开始时间
	 * \param etime 结束时间，0表示到最新数据
	 * \return Tick数据切片
	 */
	virtual WTSTickSlice*	readTickSlicesByRange(const char* stdCode, uint64_t stime, uint64_t etime = 0) override;
	
	/*!
	 * \brief 按时间范围读取K线数据切片
	 * \param stdCode 标准合约代码
	 * \param period K线周期
	 * \param stime 开始时间
	 * \param etime 结束时间，0表示到最新数据
	 * \return K线数据切片
	 */
	virtual WTSKlineSlice*	readKlineSliceByRange(const char* stdCode, WTSKlinePeriod period, uint64_t stime, uint64_t etime = 0) override;

	/*!
	 * \brief 按数量读取Tick数据切片
	 * \param stdCode 标准合约代码
	 * \param count 数据条数
	 * \param etime 结束时间，0表示到最新数据
	 * \return Tick数据切片
	 */
	virtual WTSTickSlice*	readTickSlicesByCount(const char* stdCode, uint32_t count, uint64_t etime = 0) override;
	
	/*!
	 * \brief 按数量读取K线数据切片
	 * \param stdCode 标准合约代码
	 * \param period K线周期
	 * \param count 数据条数
	 * \param etime 结束时间，0表示到最新数据
	 * \return K线数据切片
	 */
	virtual WTSKlineSlice*	readKlineSliceByCount(const char* stdCode, WTSKlinePeriod period, uint32_t count, uint64_t etime = 0) override;

private:
	std::string		_base_dir;		///< 数据文件根目录
	IBaseDataMgr*	_base_data_mgr;	///< 基础数据管理器
	IHotMgr*		_hot_mgr;		///< 热点合约管理器
	StdThreadPtr	_thrd_check;	///< 检查线程
	bool			_stopped;		///< 停止标志

	/*!
	 * \struct BarsList
	 * \brief K线数据列表结构
	 * 
	 * \details 用于缓存K线数据，包含合约信息和数据数组
	 */
	typedef struct _BarsList
	{
		std::string		_exchg;		///< 交易所代码
		std::string		_code;		///< 合约代码
		WTSKlinePeriod	_period;	///< K线周期
		std::string		_raw_code;	///< 原始合约代码

		std::vector<WTSBarStruct>	_bars;	///< K线数据数组
	} BarsList;

	typedef faster_hashmap<std::string, BarsList> BarsCache;
	BarsCache	_bars_cache;	///< K线数据缓存

	/*!
	 * \struct AdjFactor
	 * \brief 复权因子结构
	 * 
	 * \details 用于股票数据的复权处理，包含日期和复权因子
	 */
	typedef struct _AdjFactor
	{
		uint32_t	_date;		///< 复权日期
		double		_factor;	///< 复权因子
	} AdjFactor;
	typedef std::vector<AdjFactor> AdjFactorList;
	typedef faster_hashmap<std::string, AdjFactorList>	AdjFactorMap;
	AdjFactorMap	_adj_factors;	///< 复权因子映射表

	/*!
	 * \brief 获取复权因子列表
	 * \param code 合约代码
	 * \param exchg 交易所代码
	 * \param pid 品种ID
	 * \return 复权因子列表的常引用
	 */
	inline const AdjFactorList& getAdjFactors(const char* code, const char* exchg, const char* pid)
	{
		char key[20] = { 0 };
		sprintf(key, "%s.%s.%s", exchg, pid, code);
		return _adj_factors[key];
	}
};

NS_WTP_END